Building an xdg-app – part 3

Welcome back to this multi-part tutorial in how to create xdg-app applications. In part 2 we built a an xdg-app for gnome-dictionary. However, if you look closely at the commands we used you will set not much what we did was specific to this application.

In fact, the only things related to gnome-dictionary are the:

  • application id
  • source url
  • binary name
  • necessary permissions

Why is this?

It turns out that most open source applications are built in very similar ways. One can even consider this an API for building modules. And if some module does not conform to this API, then it is easy to change the upstream to conform, or if upstream is not interested, apply a local patch.

The xdg-app-builder tool that ships with xdg-app is based on this idea. You describe your application, and the modules you want to build into it, and then xdg-app-builder takes care of calling the lower-level xdg-app build commands for you.

The equivalent of what we did in part 2 is this json:

{
  "app-id": "org.gnome.Dictionary",
  "runtime": "org.gnome.Platform",
  "runtime-version": "3.20",
  "sdk": "org.gnome.Sdk",
  "command": "gnome-dictionary",
  "finish-args": [ 
     "--socket=x11", 
     "--share=network"  
  ],
  "modules": [
    {
      "name": "gnome-dictionary",
      "sources": [
        {
          "type": "archive",
          "url": "https://download.gnome.org/sources/gnome-dictionary/3.20/gnome-dictionary-3.20.0.tar.xz",
          "sha256": "efb36377d46eff9291d3b8fec37baab2355f9dc8bc7edb791b6a625574716121"
        }
      ]
    }
  ]
}

If you put this in a file called org.gnome.Dictionary.json you can build and export the app using:

$ xdg-app-builder --repo=repo appdir3 org.gnome.Dictionary.json

And to test this you use:

$ xdg-app --user update org.gnome.Dictionary
$ xdg-app run org.gnome.Dictionary

So the above commands downloaded the files, initialized the build dir, built the modules, finished the app and exported it to the repo. Just like we did before.

However, even for this simple file it did a lot of other nice things too.

  • It verified the sha256 checksum of the downloaded tarball
  • It built all sources in a fixed location (in /run/build) to ensure more repeatable builds.
  • It ran the builds without access to any part of the host filesystem, other than the directory with the extracted sources. This means less chance of the build machine details affecting the build.
  • It automatically extracted all the debug information from the installed binaries into separate files, and these were commited to a separately installable runtime called org.gnome.Dictionary.Debug.
  • Translations were also extracted to separately installable runtimes called org.gnome.Dictionary.Locale.$lang
  • It cached each stage of the build, so that if you need to rebuild the app only the modules that have changed will be rebuilt.

Other than this xdg-app-builder has a lot of useful features. The obvious one is that you can build multiple modules into the application, and you can have multiple sources for each module. Sources can be of several types. Currently it supports: archive (.tar, .zip), git, bzr, patch files, and just running shell commands.

There is also a cleanup phase that happens after the build. This phase lets you remove things that was added during the build, that will not be needed during runtime. For instance, you can remove headers, development docs and similar things here. xdg-app-builder supports two properties for this. First a list of filename patterns, and secondly a list of commands to run during the cleanup phase.

"cleanup": [ "/include", "/bin/foo-*", "*.a" ]
"cleanup-commands": [ "sed s/foo/bar/ /bin/app.sh" ]

Additionally, the cleanup property can be set on a per-module basis, and will then only match filenames that were created by that particular module.

Another special feature is the rename-icon, rename-desktop-file and rename-appdata properties which lets you rename these kinds of files to match the application id. You have to do this because upstream files don’t use the application id in the name, which is not allowed by xdg-app during export.

The nightly build of the gnome applications all are built using xdg-app-builder, and you can get a lot of example json files there, for instance a complete version of gnome-dictionary built from git.  I also have a few more examples here.

For detailed documentations on all xdg-app-builder properties. See the man page for xdg-app builder.

That is it for today. Next time we will take a look at some details about the xdg-app sandbox.